package com.example.prom.qianduoduo.y2025.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.example.prom.qianduoduo.y2025.model.MoleculeItem;
import com.example.prom.qianduoduo.y2025.model.MoleculeTargetItem;
import com.example.prom.strategy.excel.CustomCellStyleStrategy;
import com.example.prom.strategy.excel.CustomColumnWidthStrategy;
import com.example.prom.utils.DateUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

/**
 * Description
 *
 * @author DangWen
 */
public class TcmspController extends BaseController{

    public static void main(String[] args) throws Exception {
        // token需要从浏览器requestUrl中获取
        String token = "261ff8c6c82e7b529ea86d2789702a40";
        List<String> list = Arrays.asList("北五味子", "丹参", "酸枣仁");
        for (String s : list) {
            handleExcelData(token, s);
        }

    }

    private static void handleExcelData(String token, String name) throws ParseException {
        List<MoleculeItem> excelResultListSheet1 = new ArrayList<>();
        List<MoleculeTargetItem> excelResultListSheet2 = new ArrayList<>();

        WebDriver webDriver = getWebDriver();
        webDriver.get("https://www.tcmsp-e.com/tcmspsearch.php?q="+name+"&qs=herb_all_name&token="+ token);
        WebDriverWait webDriverWait = newWebDriverWait();
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(
                By.cssSelector("div.right")));
        // 获取渲染后的页面源码
        String pageSource = webDriver.getPageSource();
        // 使用JSoup解析
        Document document = Jsoup.parse(pageSource);
        Elements rows = document.select("tr[role=row]");

        for (Element row : rows) {
            String latinName = row.select("td[role=gridcell] a").text();
            // 创建对象并处理
            webDriver.get("https://www.tcmsp-e.com/tcmspsearch.php?qr="+latinName+"&qsr=herb_en_name&token="+ token);

            webDriverWait.until(ExpectedConditions.presenceOfElementLocated(
                    By.cssSelector("div.right")));

            // Process paginated tables
            List<MoleculeItem> moleculeItems = processPaginatedTables(webDriver, webDriverWait,"Ingredients");
            excelResultListSheet1.addAll(moleculeItems);
            List<MoleculeTargetItem> moleculeTargetItems = processPaginatedTables(webDriver, webDriverWait,"Related Targets");
            excelResultListSheet2.addAll(moleculeTargetItems);
            String suffix = DateUtil.formatTimeStamp(System.currentTimeMillis(), "yyyyMMddHHmmss");
            exportExcel(excelResultListSheet1, excelResultListSheet2, "D:\\dangwen\\钱多多\\" + name + suffix + ".xlsx");
        }
    }

    /**
     * Process paginated tables with multiple pages
     */
    private static <T> List<T> processPaginatedTables(WebDriver webDriver, WebDriverWait webDriverWait, String name) {
        List<T> resultList = new ArrayList<>();
        String firstPageSource = webDriver.getPageSource();
        Document firstPageDocument = Jsoup.parse(firstPageSource);
        // 分页逻辑
        Element pageElement;
        if ("Ingredients".equals(name)) {
            // Ingredients
            pageElement = firstPageDocument.select("span[class=k-pager-info k-label]").first();
        } else {
            // Related Targets
            pageElement = firstPageDocument.select("span[class=k-pager-info k-label]").get(1);
        }
//        1 - 15 of 130 items
        String pageInfo = pageElement.text();
        System.out.println("Page info: " + pageInfo);
        int totalItems = Integer.parseInt(pageInfo.replaceAll(".*of (\\d+) items", "$1"));
        Pattern pattern = Pattern.compile("(\\d+) - (\\d+) of.*");
        Matcher matcher = pattern.matcher(pageInfo);
        int itemsPerPage = 0;
        if (matcher.find()) {
            int start = Integer.parseInt(matcher.group(1));
            int end = Integer.parseInt(matcher.group(2));
            itemsPerPage = end - start + 1; // 正确计算每页数量
        }
        int totalPages = (int) Math.ceil((double) totalItems / itemsPerPage);
        System.out.println("Total pages: " + totalPages); // 输出: Total pages: 9
        int currentPage = 1;

        // Try to get total pages from the pagination info if available
        // This depends on the actual website implementation
        // For example: "Page 1 of 9"
        // String pageInfo = webDriver.findElement(By.cssSelector(".pagination-info")).getText();
        // totalPages = Integer.parseInt(pageInfo.split(" ")[2]);

        while (currentPage <= totalPages) {
            // 由于是前端分页，所以没有睡眠的必要了
//            try {
//                Thread.sleep(300 + new Random().nextInt(300));
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
            // Wait for table to load
            webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("table[role=grid]")));

            // Extract data from current page
            String pageSource = webDriver.getPageSource();
            Document document = Jsoup.parse(pageSource);
//            Elements tableElements = document.select("table[role=grid]");
            Element tableElement;
            if ("Ingredients".equals(name)){
                // Ingredients-药物成分
                tableElement = document.select("table[role=grid]").get(1);
                // 这里节点取的不对
                List<T> moleculeItems = (List<T>) extractMoleculeData(tableElement);
                resultList.addAll(moleculeItems);
            } else {
                // Related Targets-相关目标
                tableElement = document.select("table[role=grid]").get(3);
                List<T> moleculeTargetItems = (List<T>) extractMoleculeTargetData(tableElement);
                resultList.addAll(moleculeTargetItems);
            }


            // Check if there are more pages
            if (currentPage < totalPages) {
                try {
                    System.out.println("Tab Name:"+name+",Current page: " + currentPage);
                    // Click next page button
                    webDriver.findElement(By.cssSelector(".k-i-arrow-e")).click();

                    // Wait for next page to load
                    Thread.sleep(2000); // Adjust based on network speed

                    // Update current page counter
                    currentPage++;
                } catch (Exception e) {
                    System.out.println("Error navigating to next page: " + e.getMessage());
                    break;
                }
            } else {
                break;
            }
        }
        return resultList;
    }

    private static List<MoleculeTargetItem> extractMoleculeTargetData(Element tableElement) {
        Elements rows = tableElement.select("tr[role=row]");

        List<MoleculeTargetItem> list = new ArrayList<>();
        for (Element row : rows) {
            Elements cells = row.select("td[role=gridcell]");

            String molId = cells.get(0).text();
            String moleculeName = cells.get(1).select("a").text();
            String targetName = cells.get(2).select("a").text();
            String source = cells.get(3).select("a .label-success").text();
            String status = cells.get(4).text();

            // 创建对象并处理
            MoleculeTargetItem item = new MoleculeTargetItem(molId, moleculeName, targetName, source, status);
            // 这里可以添加代码将item添加到列表中或进行其他处理
            list.add(item);
        }
        return list;
    }

    /**
     * Extract molecule data from table element
     */
    private static List<MoleculeItem> extractMoleculeData(Element tableElement) {
        Elements rows = tableElement.select("tr[role=row]");

        List<MoleculeItem> list = new ArrayList<>();
        for (Element row : rows) {
            Elements cells = row.select("td[role=gridcell]");

            // Ensure we have all required columns
            String molId = cells.get(0).text().trim();
            String moleculeName = cells.get(1).select("a").text().trim();
            double mw = safeParseDouble(cells.get(2).text().trim());
            double alogp = safeParseDouble(cells.get(3).text().trim());
            int hdon = Integer.parseInt(cells.get(4).text().trim());
            int hacc = Integer.parseInt(cells.get(5).text().trim());
            double ob = safeParseDouble(cells.get(6).text().trim().replace("%", ""));
            double caco2 = safeParseDouble(cells.get(7).text().trim());
            double bbb = safeParseDouble(cells.get(8).text().trim());
            double dl = safeParseDouble(cells.get(9).text().trim());
            double fasa = safeParseDouble(cells.get(10).text().trim());
            String cells11Value = cells.get(11).text().trim();
            Double halflife = null;
            if (!cells11Value.isEmpty()) {
                halflife = Double.parseDouble(cells.get(11).text().trim());
            }
            String saveLink = cells.get(12).select("a").attr("href");

            // 应用过滤条件
            if (ob >= 30 && dl >= 0.18) {
                MoleculeItem item = new MoleculeItem(molId, moleculeName, mw, alogp, hdon, hacc, ob, caco2, bbb, dl, fasa, halflife, saveLink);
                // 这里可以添加代码将item添加到列表中或进行其他处理
                list.add(item);
            }
        }
        return list;
    }

    public static double safeParseDouble(String value) {
        if (value == null || value.trim().isEmpty()) {
            return 0.0; // 或抛出异常、返回 NaN
        }
        try {
            return Double.parseDouble(value.replace(",", ""));
        } catch (NumberFormatException e) {
            System.err.println("无法解析数值: " + value);
            return 0.0; // 或根据业务需要返回默认值
        }
    }

    public static void exportExcel(List<MoleculeItem> moleculeItems,
                                   List<MoleculeTargetItem> moleculeTargetItems,
                                   String outputFilePath) {

        // 1. 创建 ExcelWriter 对象（核心）
        ExcelWriter excelWriter = EasyExcel.write(outputFilePath).build();

        try {
            // 2. 写入第一个 Sheet
            WriteSheet sheet1 = EasyExcel.writerSheet("Ingredients")
                    .head(MoleculeItem.class)
                    .registerWriteHandler(new CustomColumnWidthStrategy())
                    .registerWriteHandler(new CustomCellStyleStrategy())
                    .build();

            excelWriter.write(moleculeItems, sheet1);

            // 3. 写入第二个 Sheet
            WriteSheet sheet2 = EasyExcel.writerSheet("Related Targets")
                    .head(MoleculeTargetItem.class)
                    .registerWriteHandler(new CustomColumnWidthStrategy())
                    .registerWriteHandler(new CustomCellStyleStrategy())
                    .build();

            excelWriter.write(moleculeTargetItems, sheet2);

            System.out.println("Excel 已成功生成两个 Sheet 于: " + outputFilePath);
        } finally {
            // 4. 必须关闭 writer 释放资源
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }


}
